<template>
  <div class="page config-algorithm">
    <div class="header">
      <span>{{ language.title }}</span>
      <div class="options">
        <el-button type="primary" @click="saveAlgoConfig" :loading="saving">保存配置</el-button>
        <el-button @click="emit('cancel')">{{ language.return }}</el-button>
      </div>
    </div>
    <div class="content">
      <div class="container" v-loading="loading">
        <div class="marker" ref="marker"></div>
        <template v-if="enable">
          <el-button type="primary" @click="createMarkItem" :disabled="!insert">{{ language.marker.create }}</el-button>
          <el-button type="primary" @click="deleteMarkItem" :disabled="!remove">{{ language.marker.remove }}</el-button>
          <el-button type="primary" @click="saveMarkData" v-if="save">{{ language.marker.save }}</el-button>
          <p style="user-select: none;">{{ language.marker.tips }}</p>
          <p>{{ `${language.marker.coordinate.canvas}: ( ${canvasCoord.x}, ${canvasCoord.y})
            ${language.marker.coordinate.actual}: ( ${realCoord.x},${realCoord.y})` }}</p>
        </template>
      </div>

      <el-form :model="data" class="right" label-width="auto">
        <el-form-item :label="language.form.algoName">
          <span>{{ props.data.algoName }}</span>
        </el-form-item>
        <el-form-item :label="language.form.algoStrategy.title">
          <el-select v-model="props.data.algoStrategy" :placeholder="language.form.placeholder"
            @change="onStrategyChange">
            <el-option :label="language.form.algoStrategy['0']" :value="0"></el-option>
            <el-option :label="language.form.algoStrategy['1']" :value="1"></el-option>
            <el-option :label="language.form.algoStrategy['2']" :value="2"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="language.form.strategyValue + ':'">
          <template v-if="props.data.algoStrategy === 0">
            <!-- 全速分析 -->
            <el-input-number v-model="props.data.strategyValue" :min="1" :precision="0" :max="25"></el-input-number>
            <span class="seconds">fps</span>
          </template>
          <template v-else-if="props.data.algoStrategy === 1">
            <el-input-number v-model="props.data.strategyValue" :min="1" :max="600"></el-input-number>
            <span class="seconds">{{ language.form.seconds }}</span>
          </template>
          <template v-else>
            <el-input-number v-model="props.data.strategyValue" :min="0" :max="10000"></el-input-number>
            <span class="seconds">{{ language.form.seconds }}</span>
          </template>
        </el-form-item>
        <el-form-item :label="language.form.score">
          <el-input-number v-model="data.score" :min="0" :max="1" :step="0.1"></el-input-number>
          <span class="seconds"></span>
        </el-form-item>
        <el-form-item :label="language.form.alarmPeriod">
          <el-input-number v-model="data.alarmPeriod" :min="0" :max="99999"></el-input-number>
          <span class="seconds">{{ language.form.seconds }}</span>
        </el-form-item>
        <el-form-item :label="language.form.alarmLevel">
          <el-select v-model="data.alarmLevel" :placeholder="language.form.placeholder">
            <el-option label="1" :value="1"></el-option>
            <el-option label="2" :value="2"></el-option>
            <el-option label="3" :value="3"></el-option>
            <el-option label="4" :value="4"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="language.form.yuzhi.title">
          <div style="flex:1">
            <el-input v-model="yuzhi" size="small" type="number" autocomplete="off" :min="0" :max="60"
              style="width: 80px; margin-right:10px"></el-input>
            <el-button size="small" @click="confirm">{{ language.form.yuzhi.confirm }}</el-button>
            <el-button size="small" @click="clean">{{ language.form.yuzhi.clean }}</el-button>
            <div>{{ data.analysisValue }}</div>
          </div>
        </el-form-item>
        <el-form-item :label="language.form.analysisInterval">
          <el-input-number v-model="data.analysisInterval" :min="0" :max="60"></el-input-number>
          <span class="seconds">{{ language.form.seconds }}</span>
        </el-form-item>
        <el-form-item :label="language.form.setRegion">
          <el-button :type="current === 'analysisRegion' ? 'warning' : 'primary'" @click="startMark('analysisRegion')"
            size="small">{{ language.form.setRegion }}</el-button>
          <el-tooltip effect="dark" :content="JSON.stringify(data.analysisRegion)" placement="top">
            <span class="area">{{ data.analysisRegion }}</span>
          </el-tooltip>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, computed } from "vue";
import { ElMessage } from 'element-plus';
import { channelController } from '@/services/cameraApi'
import imgPlugin from '@wanglin1994/markjs/src/plugins/img';
import Markjs from '@wanglin1994/markjs';

Markjs.use(imgPlugin, 0);

// 语言配置 - 简化版本，直接定义中文
const language = {
  title: "配置算法",
  return: "返回",
  marker: {
    create: "新建标注",
    remove: "删除标注",
    save: "保存新标注",
    tips: "鼠标左键单击标注进行编辑，左键双击完成标注",
    coordinate: { canvas: "画布坐标", actual: "实际坐标" }
  },
  form: {
    algoName: "算法名称",
    algoStrategy: {
      title: "算法策略",
      0: "全速分析",
      1: "算力轮询",
      2: "定时抽帧",
    },
    strategyValue: "策略参数",
    placeholder: "请选择",
    seconds: "秒",
    score: "置信度",
    alarmPeriod: "报警间隔",
    alarmLevel: "算法报警等级",
    yuzhi: {
      title: "分析阈值",
      confirm: "确认",
      clean: "清空",
    },
    analysisInterval: "分析间隔",
    analysisRegion: "分析区域",
    setRegion: "设置区域"
  },
  yuzhi: {
    length: "最多只能输入10个",
    number: "必须输入正整数"
  },
  mark: {
    count: "至少需要绘制三个端点",
    cross: "线段不允许交叉"
  },
  image: "获取图片失败"
}

const props = defineProps({
  data: { type: Object, required: true },
  deviceId: { type: String, required: true },
  channelId: { type: String, required: true },
})

const emit = defineEmits(['cancel', 'save'])
const canvasCoord = ref({ x: 0, y: 0 });
const realCoord = ref({ x: 0, y: 0 });

// 保存状态
const saving = ref(false);

// 创建一个响应式的数据对象，与 props.data 同步
const data = ref({
  score: 0.5,
  alarmPeriod: 30,
  alarmLevel: 1,
  analysisValue: [],
  analysisInterval: 0,
  analysisRegion: [],
  ...props.data
})

// 分析阈值
const yuzhi = ref("")

const confirm = () => {
  const value = yuzhi.value
  if (/^\d+$/.test(value)) {
    if (data.value.analysisValue.length !== 10) {
      data.value.analysisValue.push(Number(value));
    } else {
      ElMessage.error(language.yuzhi.length)
    }
  } else {
    ElMessage.error(language.yuzhi.number)
  }
  yuzhi.value = "";
}

const clean = () => {
  data.value.analysisValue = []
}

// 是否显示按钮区
const enable = ref(false);

// 是否能点击新增
const insert = ref(false);

// 是否能删除
const remove = ref(false);

// 是否能保存
const save = ref(false);

const loading = ref(false);

const img = ref(null);

let instance = null;

const marker = ref(null);

// 策略变化时，策略默认值取值范围
const onStrategyChange = (value) => {
  if (value === 0) {
    props.data.strategyValue = 15
  } else if (value === 1) {
    props.data.strategyValue = 10
  } else {
    props.data.strategyValue = 1
  }
}

// 初始化标注插件
const initMarker = () => {
  // 推荐用法
  instance = new Markjs({
    el: marker.value,
    img: img.value,
    max: 3,
    hoverActive: false,
    dbClickActive: true,
    noCrossing: true,
    enableAddPoint: true,
    area: true,
    single: true,
    showPen: false,
    singleClickComplete: true,
    pointType: 'circle',
    pointWidth: 2,
    pointStyle: { lineWidth: 2, strokeColor: '#0088FF', fillColor: '#fff' },
    elBg: "#eee",
    lineType: 'line',
    strokeStyle: { lineWidth: 2, strokeColor: 'red' },
    fillColor: 'rgba(0,136,255,0.30)',
    dbClickRemovePoint: true
  })

  instance.on('NOT-ENOUGH-END-POINTS', () => ElMessage.warning(language.mark.count))

  // 使用插件提供的鼠标移动事件
  instance.on('MOUSEMOVE', (e) => {
    canvasCoord.value = {
      x: e.offsetX,
      y: e.offsetY
    };

    realCoord.value = {
      x: Math.round(e.offsetX / canvas.width * size.width),
      y: Math.round(e.offsetY / canvas.height * size.height)
    };
  });

  instance.on('DOUBLE-CLICK', (e) => {
    const { markItemList, curEditingMarkItem } = instance.getState();
    if (Array.isArray(markItemList) && markItemList.length && curEditingMarkItem) {
      const { pointArr } = curEditingMarkItem
      if (Array.isArray(pointArr) && pointArr.length === 3) {
        const prinot = { x: e.offsetX, y: e.offsetY }
        pointArr.push(prinot);
        instance.exitCreate();
        instance.reset();
        showMark(pointArr.map(e => ({ x: e.x / canvas.width, y: e.y / canvas.height })));
      }
    }
  })

  instance.on('LINE-CROSS', () => ElMessage.warning(language.mark.cross))

  instance.on('NOT-ENOUGH-POINTS-REMOVE', () => ElMessage.warning(language.mark.count))
}

// 当前选择
const current = ref(null);

const showMark = (list) => {
  instance.createMarkItem({ pointArr: list });
  instance.disableEdit();
}

// 开始编辑
const startMark = (key) => {
  instance.deleteAllMarkItem();
  instance.enableEdit();
  current.value = key
  enable.value = true
  const regionData = data.value[key]
  if (Array.isArray(regionData) && regionData.length) {
    showMark(regionData.map(e => ({ x: e.x / size.width, y: e.y / size.height })));
    remove.value = true
    insert.value = false
    save.value = false
  } else {
    insert.value = true
    remove.value = false
    save.value = false
  }
}

const size = { width: 1920, height: 1080 }

const canvas = {}

// 保存标注数据
const saveMarkData = () => {
  save.value = false;
  const list = instance.getMarkData();
  const markData = list[0]?.pointArr || [];
  if (Array.isArray(markData) && markData.length) {
    markData.forEach(e => {
      e.x = Math.round(e.x * size.width);
      e.y = Math.round(e.y * size.height);
    })
  }
  data.value[current.value] = markData;
}

// 创建项目
const createMarkItem = () => {
  save.value = true;
  insert.value = false;
  remove.value = true;
  instance.enableEdit();
  instance.createMarkItem();
}

// 删除项目
const deleteMarkItem = () => {
  save.value = false;
  remove.value = false;
  insert.value = true;
  data.value[current.value] = [];
  instance.deleteAllMarkItem();
  instance.disableEdit();
}

// 保存算法配置
const saveAlgoConfig = async () => {
  try {
    saving.value = true

    // 构建保存参数
    const params = {
      deviceId: props.deviceId,
      channelId: props.channelId,
      algoId: props.data.algoId,
      algoStrategy: data.value.algoStrategy,
      strategyValue: data.value.strategyValue,
      score: data.value.score,
      alarmPeriod: data.value.alarmPeriod,
      alarmLevel: data.value.alarmLevel,
      analysisValue: data.value.analysisValue,
      analysisInterval: data.value.analysisInterval,
      analysisRegion: data.value.analysisRegion
    }

    await channelController.setChannelAlgo(params)
    ElMessage.success('保存成功')

    // 通知父组件保存成功
    emit('save', params)
  } catch (error) {
    console.error('保存算法配置失败:', error)
    ElMessage.error(error.message || error || '保存失败')
  } finally {
    saving.value = false
  }
}

// 获取相机图片
const getCameraImage = async () => {
  try {
    loading.value = true;
    const params = { deviceId: props.deviceId, channelId: props.channelId }
    const { imgUrl } = await channelController.getImage(params);
    if (imgUrl) {
      const fullUrl = import.meta.env.VITE_VIDEO_API + imgUrl;
      img.value = fullUrl;
      const image = new Image();
      image.onload = () => {
        size.width = image.naturalWidth;
        size.height = image.naturalHeight;
      };
      image.onerror = () => {
        ElMessage.error(language.image)
      };
      image.src = fullUrl;
    }
  } catch (error) {
    ElMessage.error(error)
  } finally {
    await nextTick();
    if (marker.value) {
      const { offsetWidth, offsetHeight } = marker.value;
      canvas.width = offsetWidth
      canvas.height = offsetHeight
      initMarker();
      loading.value = false;
    }
  }
}

getCameraImage();
</script>

<style lang="scss" scoped>
@use '@/styles/variables.scss' as *;

.config-algorithm {
  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
  }

  .content {
    user-select: none;
    height: calc(100% - 42px);
    display: flex;
    justify-content: space-between;
    align-content: flex-start;

    .container {
      width: 1155px;

      .marker {
        width: 100%;
        height: 650px;
        background-color: #f5f5f5;
        margin-bottom: 10px;
      }
    }

    .el-form {
      flex: 1;
      margin-left: 50px;
      padding-right: 50px;

      .el-form-item__content {
        .el-select {
          flex: 1;
        }
      }
    }

    .el-input-number {
      flex: 1;
    }

    .seconds {
      display: inline-block;
      height: 32px;
      width: 80px;
      line-height: 32px;
      text-align: center;
      background-color: #f5f7fa;
      border-top-right-radius: 4px;
      border-bottom-right-radius: 4px;
    }

    .area {
      flex: 1;
      margin-left: 10px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    p {
      margin-bottom: 0;
    }
  }
}
</style>
